home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / machserver / 1.098 / mach / sun3.md / machTrap.s < prev    next >
Text File  |  1991-07-26  |  16KB  |  680 lines

  1. |* machTrap.s -
  2. |*
  3. |*     Contains the trap handlers.
  4. |*
  5. |* Copyright (C) 1985 Regents of the University of California
  6. |* All rights reserved.
  7. |*
  8.  
  9. #include "machConst.h"
  10. #include "machAsmDefs.h"
  11.  
  12. .data
  13. .asciz "$Header: /sprite/src/kernel/mach/sun3.md/RCS/machTrap.s,v 9.5 91/07/26 17:03:06 shirriff Exp $ SPRITE (Berkeley)"
  14. .even
  15. .text
  16.  
  17. |*
  18. |* ----------------------------------------------------------------------------
  19. |*
  20. |* Trap handling --
  21. |*
  22. |*    Handle exceptions.  In all cases except kernel calls, call
  23. |*    the C trap handler.  See the kernel call code below.
  24. |*
  25. |* Results:
  26. |*    None.
  27. |*
  28. |* Side effects:
  29. |*    None.
  30. |*
  31. |* ----------------------------------------------------------------------------
  32. |*
  33.     .globl    MachReset
  34. MachReset:
  35.     CallTrapHandler(MACH_RESET)
  36.  
  37.     .globl    MachBusError
  38. MachBusError:
  39.     CallTrapHandler(MACH_BUS_ERROR)
  40.  
  41.     .globl    MachAddrError
  42. MachAddrError:
  43.     CallTrapHandler(MACH_ADDRESS_ERROR)
  44.  
  45.     .globl    MachIllegalInst
  46. MachIllegalInst:
  47.     CallTrapHandler(MACH_ILLEGAL_INST)
  48.  
  49.     .globl    MachZeroDiv
  50. MachZeroDiv:
  51.     CallTrapHandler(MACH_ZERO_DIV)
  52.  
  53.     .globl    MachChkInst
  54. MachChkInst:
  55.     CallTrapHandler(MACH_CHK_INST)
  56.  
  57.     .globl    MachTrapv
  58. MachTrapv:
  59.     CallTrapHandler(MACH_TRAPV)
  60.  
  61.     .globl    MachPrivVio
  62. MachPrivVio:
  63.     CallTrapHandler(MACH_PRIV_VIOLATION)
  64.  
  65.     .globl    MachTraceTrap
  66. MachTraceTrap:
  67.     CallTrapHandler(MACH_TRACE_TRAP)
  68.  
  69.     .globl    MachEmu1010
  70. MachEmu1010:
  71.     CallTrapHandler(MACH_EMU1010)
  72.  
  73.     .globl    MachEmu1111
  74. MachEmu1111:
  75.     CallTrapHandler(MACH_EMU1111)
  76.  
  77.     .globl    MachFmtError    
  78. MachFmtError:
  79.     CallTrapHandler(MACH_STACK_FMT_ERROR)
  80.  
  81.     .globl    MachUninitVect
  82. MachUninitVect:
  83.     CallTrapHandler(MACH_UNINIT_VECTOR)
  84.  
  85.     .globl    MachSigRetTrap
  86. MachSigRetTrap:
  87.     CallTrapHandler(MACH_SIG_RET_TRAP)
  88.  
  89.     .globl    MachBadTrap
  90. MachBadTrap:
  91.     CallTrapHandler(MACH_BAD_TRAP)
  92.  
  93.     .globl    MachBrkptTrap
  94.     .globl _MachBrkptTrap
  95. _MachBrkptTrap:
  96. MachBrkptTrap:
  97.     CallTrapHandler(MACH_BRKPT_TRAP)
  98.  
  99. .globl MachFpUnorderedCond
  100. MachFpUnorderedCond:
  101.     CallTrapHandler(MACH_FP_UNORDERED_COND)
  102.  
  103. .globl MachFpInexactResult
  104. MachFpInexactResult:
  105.     CallTrapHandler(MACH_FP_INEXACT_RESULT)
  106.  
  107. .globl MachFpZeroDiv
  108. MachFpZeroDiv:
  109.     CallTrapHandler(MACH_FP_ZERO_DIV)
  110.  
  111. .globl MachFpUnderflow
  112. MachFpUnderflow:
  113.     CallTrapHandler(MACH_FP_UNDERFLOW)
  114.  
  115. .globl MachFpOperandError
  116. MachFpOperandError:
  117.     CallTrapHandler(MACH_FP_OPERAND_ERROR)
  118.  
  119. .globl MachFpOverflow
  120. MachFpOverflow:
  121.     CallTrapHandler(MACH_FP_OVERFLOW)
  122.  
  123. .globl MachFpNaN
  124. MachFpNaN:
  125.     CallTrapHandler(MACH_FP_NAN)
  126.  
  127.  
  128.  
  129. |*
  130. |* ----------------------------------------------------------------------
  131. |*
  132. |* MachUnixSyscallTrap --
  133. |*
  134. |*    This is the code entered on Unix compatible system call traps.
  135. |*    The code below is tuned to get into and out of kernel calls as
  136. |*      fast as possible.
  137. |*
  138. |* Results:
  139. |*    If the carry flag is clear, d0 contains the result of the system call.
  140. |*      If the carry flag is set, the system call failed, and d0 contains
  141. |*      the errno.
  142. |*
  143. |* Side effects:
  144. |*    Depends on the kernel call.
  145. |*
  146. |* ----------------------------------------------------------------------
  147. |*
  148.  
  149.     .globl MachUnixSyscallTrap
  150. MachUnixSyscallTrap:
  151.  
  152.     |* Save the address registers we use, and the sp.
  153.     |* We used to not save a0, a1, but the Sun longjmp code counts
  154.     |* on a0 being preserved.
  155.     movl    a0, sp@-
  156.     movl    a1, sp@-
  157.     movl    a2, sp@-
  158.     movl    a3, sp@-
  159.     movl    sp, a3
  160.  
  161.     movl    _machCurStatePtr, a0
  162.  
  163.     |* Save d0, because the Sigreturn system call needs it.
  164.     |* (Boneheaded SunOS convention for that system call!)
  165.     movl    d0, a0@(MACH_TRAP_REGS_OFFSET + 0)
  166.  
  167.  
  168.     |* Save the exc stack pointer since we need that too.
  169.     |* We should probably use special handling for some of this.
  170.     lea    sp@(16), a1
  171.     movl    a1, a0@(MACH_EXC_STACK_PTR_OFFSET)
  172.     |* Clear the carry bit to indicate no error.
  173.     movw    a1@, d0
  174.     andw    #~0x1, d0
  175.     movw    d0, a1@
  176.  
  177.     |* Pop the call number into d0
  178.     movc    usp, a1
  179.     movl    a1@+, d0
  180.     movc    a1, usp
  181.  
  182.     |*
  183.     |* Always save the user stack pointer because it can be needed
  184.     |* while processing the system call.
  185.     |*
  186.     movl    a1, a0@(MACH_USER_SP_OFFSET)
  187.  
  188.     |*
  189.     |* Store this kernel call in the last kernel call variable.
  190.     |*
  191.     movl    d0, a0@(MACH_LAST_SYS_CALL_OFFSET)
  192.  
  193.     |*
  194.     |* If this is a fork kernel call, save the registers in the PCB.
  195.     |* This is a hack, and should eventually go away by adding another
  196.     |* parameter to fork, which gives the address of an area of
  197.     |* memory containing the process' saved state.
  198.     |*
  199.  
  200.     cmpl    #2, d0
  201.     beqs    0f
  202.     cmpl    #66, d0
  203.     bnes    1f
  204. 0:
  205.     moveml    #0xffff, a0@(MACH_TRAP_REGS_OFFSET)
  206.     movl    sp@(0), a1    | a3
  207.     movl    a1, a0@(MACH_TRAP_REGS_OFFSET+48)
  208.     movl    sp@(4), a1    | a2
  209.     movl    a1, a0@(MACH_TRAP_REGS_OFFSET+44)
  210.     movl    sp@(8), a1    | a1
  211.     movl    a1, a0@(MACH_TRAP_REGS_OFFSET+40)
  212.     movl    sp@(12), a1    | a0
  213.     movl    a1, a0@(MACH_TRAP_REGS_OFFSET+32)
  214.  
  215.     SaveUserFpuState();
  216.  
  217. 1:
  218.     |*
  219.     |* Check number of kernel call for validity.
  220.     |*
  221.  
  222.     cmpl    _sysUnixNumSyscalls, d0
  223.     bges     2f
  224.  
  225.     |*
  226.     |* Copy the arguments from user space and push them onto the stack.
  227.     |*
  228.  
  229.     lsll    #3, d0
  230.     addl    #_sysUnixSysCallTable, d0
  231.     movl    d0, a2
  232.     movl    a2@(4), d1
  233.     movl    d1, sp@-
  234.     beqs    4f
  235.     subql   #1, d1
  236.     addl    #8, a1
  237.     lsll    #2, d1
  238.     addl    d1, a1
  239.     lsrl    #2, d1
  240.  
  241.     |* Allow page faults in the copy-in.
  242.  
  243.     .globl _MachFetchArgs2
  244. _MachFetchArgs2:
  245. 3:    
  246.     movl    a1@-, sp@-
  247.     dbra    d1, 3b
  248.     .globl _MachFetchArgsEnd2
  249. _MachFetchArgsEnd2:
  250. 4:
  251.     movl    a2@, a1
  252.     jsr     a1@
  253.  
  254.     |*
  255.     |* Disable interrupts and see if any special processing must
  256.     |* be done on the process.  Note:  this is checking the
  257.     |* specialHandling field of the process control block, and depends
  258.     |* on the fact that specialHandling follows immediately after the
  259.     |* kcallTable field.
  260.     |*
  261.  
  262.     movl    _machCurStatePtr, a0
  263.     movl    a0@(MACH_USER_SP_OFFSET), a2 | restore the (new) SP
  264.     movc    a2, usp
  265.  
  266.     movl    _proc_RunningProcesses, a0
  267.     movl    a0@, a2            | d1 now has PCB address.
  268.     addl    _machKcallTableOffset, a2
  269.                     | a2 now has address of kcallTable
  270.                     | field in PCB.
  271.     movw    #0x2700, sr        | Disable interrupts.
  272.     tstl    a2@(4)            | Check specialHandling
  273.     bnes    6f
  274. 5:
  275.     movl    a3, sp
  276.     movl    sp@+, a3
  277.     movl    sp@+, a2
  278.     movl    sp@+, a1
  279.     movl    sp@+, a0
  280.     cmpl    #-1, d0
  281.     beqs    7f
  282.     rte
  283. 7:
  284.     movw    sp@, d0        | Set the carry bit to indicate error
  285.     orw    #0x1, d0
  286.     movw    d0, sp@
  287.     movel    _proc_RunningProcesses,a0    | Move errno into d0
  288.     movel    a0@,a0
  289.     movel    a0@(MACH_UNIX_ERRNO_OFFSET),d0
  290.     rte
  291.  
  292. 2:
  293.     movl    a3, sp
  294.     movl    sp@+, a3
  295.     movl    sp@+, a2
  296.     movl    sp@+, a1
  297.     movl    sp@+, a0
  298.     movw    sp@, d0        | Set the carry bit to indicate error
  299.     orw    #0x1, d0
  300.     movw    d0, sp@
  301.     movel   #22, d0        | Return EINVAL
  302.     rte
  303.  
  304. 6:
  305.     |*
  306.     |* Something's up with the process (context switch, maybe, or
  307.     |* single-step mode?).  Restore the stack to what it was at
  308.     |* the beginning of the kernel call, then go through a slow
  309.     |* trap-processing procedure to take special action.
  310.     |*
  311.     |* We have to make sure we do the right thing with errno,
  312.     |* even if special handling is set.
  313.     |*
  314.  
  315.     movl    a3, sp            | Pop kcall args off stack.
  316.     |*clrl    a2@(4)
  317.     movw    #0x2000, sr
  318.     movl    sp@+, a3
  319.     movl    sp@+, a2
  320.     movl    sp@+, a1
  321.     movl    sp@+, a0
  322.     cmpl    #-1, d0
  323.     beqs    7f
  324.     CallTrapHandler(MACH_UNIX_SYSCALL_TRAP)
  325. 7:
  326.     movw    sp@, d0        | Set the carry bit to indicate error
  327.     orw    #0x1, d0
  328.     movw    d0, sp@
  329.     movel    _proc_RunningProcesses,a0    | Move errno into d0
  330.     movel    a0@,a0
  331.     movel    a0@(MACH_UNIX_ERRNO_OFFSET),d0
  332.     CallTrapHandler(MACH_UNIX_SYSCALL_TRAP)
  333.  
  334.  
  335. |*
  336. |* ----------------------------------------------------------------------
  337. |*
  338. |* MachSyscallTrap --
  339. |*
  340. |*    This is the code entered on system call traps.  The code below
  341. |*    is tuned to get into and out of kernel calls as fast as possible.
  342. |*
  343. |* Results:
  344. |*    Returns a status to the caller in d0.
  345. |*
  346. |* Side effects:
  347. |*    Depends on the kernel call.
  348. |*
  349. |* ----------------------------------------------------------------------
  350. |*
  351.  
  352.     .globl _machMaxSysCall, _machKcallTableOffset, _machArgOffsets
  353.     .globl _machArgDispatch, _machCurStatePtr
  354.     .globl _sys_NumCalls, _proc_RunningProcesses
  355.     .globl MachSyscallTrap
  356. MachSyscallTrap:
  357.  
  358.     |*
  359.     |* Always save the user stack pointer because it can be needed
  360.     |* while processing the system call.
  361.     |*
  362.     movl    _machCurStatePtr, a0
  363.     movc    usp, a1
  364.     movl    a1, a0@(MACH_USER_SP_OFFSET)
  365.  
  366.     |*
  367.     |* If this is a fork kernel call, save the registers in the PCB.
  368.     |* This is a hack, and should eventually go away by adding another
  369.     |* parameter to fork, which gives the address of an area of
  370.     |* memory containing the process' saved state.
  371.     |*
  372.  
  373.     tstl    d0
  374.     jne    1f
  375.     moveml    #0xffff, a0@(MACH_TRAP_REGS_OFFSET)
  376.     movl    sp, a0@(MACH_EXC_STACK_PTR_OFFSET)
  377.     SaveUserFpuState();
  378.  
  379.     |*
  380.     |* Save registers used here:  two address registers and sp.
  381.     |*
  382.  
  383. 1:    movl    a2, sp@-
  384.     movl    a3, sp@-
  385.     movl    sp, a3
  386.  
  387.     |*
  388.     |* Check number of kernel call for validity.
  389.     |*
  390.  
  391.     cmpl    _machMaxSysCall, d0
  392.     jls    2f
  393.     movl    #20002, d0
  394.     jra    return
  395.  
  396. 2:
  397.     |*
  398.     |* Store this kernel call in the last kernel call variable.
  399.     |*
  400.     movl    d0, a0@(MACH_LAST_SYS_CALL_OFFSET)
  401.  
  402.     |*
  403.     |* Increment a count of the number of times this kernel call
  404.     |* has been invoked.
  405.     |*
  406.     asll    #2, d0            | Used to index into tables.
  407.     movl    #_sys_NumCalls, a0
  408.     addql    #1, a0@(0, d0:w)
  409.  
  410.     |*
  411.     |* Copy the arguments from user space and push them onto the
  412.     |* stack.  Note:  this code interacts heavily with the C code
  413.     |* in Mach_InitSyscall().  If you change one, be sure to change
  414.     |* the other.
  415.     |*
  416.  
  417.     movc    usp, d1
  418.     movl    #_machArgOffsets, a0
  419.     addl    a0@(0, d0:w), d1
  420.     movl    d1, a0
  421.     movl    #_machArgDispatch, a1
  422.     movl    a1@(0, d0:w), a1
  423.     jmp    a1@
  424.  
  425.     .globl _MachFetchArgs
  426. _MachFetchArgs:
  427.     movl    a0@-, sp@-        | 16 argument words.
  428.     movl    a0@-, sp@-
  429.     movl    a0@-, sp@-
  430.     movl    a0@-, sp@-
  431.     movl    a0@-, sp@-        | 12 argument words.
  432.     movl    a0@-, sp@-
  433.     movl    a0@-, sp@-
  434.     movl    a0@-, sp@-
  435.     movl    a0@-, sp@-        | 8 argument words.
  436.     movl    a0@-, sp@-
  437.     movl    a0@-, sp@-
  438.     movl    a0@-, sp@-
  439.     movl    a0@-, sp@-        | 4 argument words.
  440.     movl    a0@-, sp@-
  441.     movl    a0@-, sp@-
  442.     movl    a0@-, sp@-
  443.  
  444.     .globl _MachFetchArgsEnd
  445. _MachFetchArgsEnd:            | Marks last place where PC could be
  446.                     | when a page fault occurs while
  447.                     | fetching arguments.  Needed to
  448.                     | distinguish a page fault during
  449.                     | arg fetch (which is OK) from other
  450.                     | page faults in the kernel, which are
  451.                     | fatal errors.
  452.  
  453.     |*
  454.     |* Find the location in the current process's control block
  455.     |* of the trapFlags and kcallTable fields.  Then lookup the
  456.     |* address of the kernel-call handling routine and invoke it.
  457.     |*
  458.  
  459.     movl    _proc_RunningProcesses, a0
  460.     movl    a0@, d1            | d1 now has PCB address.
  461.     addl    _machKcallTableOffset, d1
  462.     movl    d1, a2            | a2 now has address of kcallTable
  463.                     | field in PCB.
  464.     movl    a2@, a0            | a0 points to 0th entry in table.
  465.     movl    a0@(0, d0:w), a1
  466.     jsr    a1@            | Dispatches to the top-level kernel
  467.                     | call procedure.
  468.  
  469.     |*
  470.     |* Disable interrupts and see if any special processing must
  471.     |* be done on the process.  Note:  this is checking the
  472.     |* specialHandling field of the process control block, and depends
  473.     |* on the fact that specialHandling follows immediately after the
  474.     |* kcallTable field, whose address was loaded into a2 above.
  475.     |*
  476.  
  477.     movl    a3, sp            | Pop kcall args off stack.
  478.     movw    #0x2700, sr        | Disable interrupts.
  479.     tstl    a2@(4)
  480.     jeq    return
  481.  
  482.     |*
  483.     |* Something's up with the process (context switch, maybe, or
  484.     |* single-step mode?).  Restore the stack to what it was at
  485.     |* the beginning of the kernel call, then go through a slow
  486.     |* trap-processing procedure to take special action.
  487.     |*
  488.  
  489.     clrl    a2@(4)
  490.     movw    #0x2000, sr
  491.     movl    sp@+, a3
  492.     movl    sp@+, a2
  493.     CallTrapHandler(MACH_SYSCALL_TRAP)
  494.  
  495. return:
  496.     movl    sp@+, a3
  497.     movl    sp@+, a2
  498.     rte
  499.  
  500. /*
  501.  *-------------------------------------------------------------------------
  502.  *
  503.  * MachReturnFromUserTrap --
  504.  *
  505.  *    Routine to return from a trap handler.  Called by CallTrapHandler
  506.  *    macro after have returned from MachTrap.  The proper action is
  507.  *    taken depending on the error code and then an rte to user space
  508.  *    is performed.
  509.  *
  510.  *-------------------------------------------------------------------------
  511.  */
  512.     .globl MachReturnFromUserTrap
  513. MachReturnFromUserTrap:
  514.  
  515. |*
  516. |* Take proper action depending on the return code.
  517. |*
  518.         cmpl     #MACH_OK, d0
  519.         beq     normReturn
  520.     cmpl    #MACH_KERN_ERROR, d0
  521.     beq    kernError
  522.     cmpl    #MACH_SIG_RETURN, d0
  523.     beq    sigReturn
  524. |*
  525. |* Bogus return code so trap to debugger.
  526. |*
  527.     jra     _Dbg_Trap
  528.  
  529. sigReturn:
  530. |*
  531. |* Are returning from a signal handler.  First get pointer to
  532. |* mach state structure.
  533. |*
  534.     movl    _machCurStatePtr, a0
  535. |*
  536. |* The saved stack pointer points to where the exception stack is to
  537. |* be restored at.
  538. |*
  539.     movl    a0@(MACH_TRAP_REGS_OFFSET + 60), sp
  540.     movl    sp, a0@(MACH_EXC_STACK_PTR_OFFSET)    
  541. |*
  542. |* Call bcopy((Address)excStack, (Address)sp, sizeof(excStack));
  543. |*
  544.     movl    sp, d0
  545.     movl    a0@(MACH_SIG_EXC_STACK_SIZE_OFFSET), sp@-
  546.     movl    d0, sp@-
  547. |*    movl    sp, sp@-
  548.     pea    a0@(MACH_SIG_EXC_STACK_OFFSET)
  549.     jsr    _bcopy
  550.     addl    #12, sp
  551. |*
  552. |* Call the normal return from trap return MachUserReturn(procPtr, &excStack)
  553. |* after enabling interrupts because they were disabled when we were called.
  554. |*
  555.     movw    #0x2000, sr
  556.     movl    _proc_RunningProcesses, a0
  557.     movl    a0@, sp@-
  558.     jsr    _MachUserReturn
  559. |*
  560. |* Do a normal return.
  561. |*
  562.     jra    normReturn
  563.  
  564. kernError:
  565. |*
  566. |* Got a fatal kernel error.  First sync disks, then restore the registers so
  567. |* that the debugger doesn't have to rely on being able to get registers from
  568. |* the proc table and then move the stack pointer back so that the trap code
  569. |* and bus error register are visible.
  570. |*
  571.     jsr    _Sys_SyncDisks
  572.     RestoreUserFpuState()
  573.     RestoreUserRegs()
  574.     subl    #MACH_TRAP_INFO_SIZE, sp
  575.     jra     _Dbg_Trap
  576.  
  577. normReturn:
  578. |*
  579. |* Normal return from trap (no errors).
  580. |*
  581.  
  582.     RestoreUserFpuState()
  583.     RestoreUserRegs()
  584.         rte
  585.  
  586.  
  587. /*
  588.  * ----------------------------------------------------------------------------
  589.  *
  590.  * RestoreKernRegs --
  591.  *
  592.  *      Restore the 4 saved temporary registers from the stack after moving
  593.  *    the stack pointer past the trap code and bus error register.
  594.  *
  595.  * ----------------------------------------------------------------------------
  596.  */
  597. #define RestoreKernRegs() \
  598.     addql    #8, sp; \
  599.     moveml    sp@+, #0x0303
  600.  
  601.  
  602. /*
  603.  *-------------------------------------------------------------------------
  604.  *
  605.  * MachReturnFromKernTrap --
  606.  *
  607.  *    Routine to return from a trap handler.  Called by CallTrapHandler
  608.  *    macro after have returned from MachTrap.  The proper action is
  609.  *    taken depending on the error code and then an rte to kern space
  610.  *    is performed.
  611.  *
  612.  *-------------------------------------------------------------------------
  613.  */
  614.     .globl MachReturnFromKernTrap
  615. MachReturnFromKernTrap:
  616.  
  617. |*
  618. |* Take proper action depending on the return code.
  619. |*
  620.         cmpl     #MACH_OK, d0
  621.         beq     kernNormReturn
  622.     cmpl    #MACH_KERN_ERROR, d0
  623.     beq    kernKernError
  624.     cmpl    #MACH_USER_ERROR, d0
  625.     beq    kernUserError
  626.  
  627. |*
  628. |* Bogus return code so trap to debugger.
  629. |*
  630.     jra     _Dbg_Trap
  631.  
  632. kernUserError:
  633. |*
  634. |* Got an error on a copy in from user space.  Blow away the
  635. |* exception stack and return SYS_ARG_NOACCESS to the function doing the copy.
  636. |* We have to compute the exception size of the exception stack from the
  637. |* vector offset register.
  638. |*
  639.     RestoreKernRegs()
  640.     clrl    d0
  641.     movw    sp@(6), d0        | D0 = VOR
  642.     lsrl    #8, d0            | DO >> 12 to get to stack format
  643.     lsrl    #4, d0
  644.     cmpl    #MACH_MC68010_BUS_FAULT, d0
  645.     bne    1f
  646.     addl    #MACH_MC68010_BUS_FAULT_SIZE, sp
  647.     bra    4f
  648. 1:    cmpl    #MACH_SHORT_BUS_FAULT, d0
  649.     bne    2f
  650.     addl    #MACH_SHORT_BUS_FAULT_SIZE, sp
  651.     bra    4f
  652. 2:    cmpl    #MACH_LONG_BUS_FAULT, d0
  653.     bne    3f
  654.     addl    #MACH_LONG_BUS_FAULT_SIZE, sp
  655.     bra    4f
  656. 3:    trap    #15
  657.  
  658. 4:    movl    #0x20000, d0
  659.     rts
  660.  
  661. kernKernError:
  662. |*
  663. |* Got a fatal kernel error.  First sync disks, then restore the registers so
  664. |* that the debugger doesn't have to rely on being able to get registers from
  665. |* the proc table and then move the stack pointer back so that the trap code
  666. |* and bus error register are visible.
  667. |*
  668.     jsr    _Sys_SyncDisks
  669.     RestoreKernRegs()
  670.     subl    #MACH_TRAP_INFO_SIZE, sp
  671.     jra     _Dbg_Trap
  672.  
  673. kernNormReturn:
  674. |*
  675. |* Normal return from trap (no errors).
  676. |*
  677.     RestoreKernRegs()
  678.         rte
  679.  
  680.